#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <poll.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define INFO(fmt,...) printf("file:[%s],line:[%d]"fmt,__FILE__,__LINE__,##__VA_ARGS__);

int main(int argc,const char* argv[])
{
    if(argc != 3){
        INFO("argc is invalid,argc must be 3");
        exit(-1);
    }

    int sockfd = -1;
    int acceptfd = -1;
    struct sockaddr_in serveraddr,clientaddr;
    socklen_t len = sizeof(serveraddr);

    memset(&serveraddr,0,sizeof(serveraddr));
    memset(&clientaddr,0,sizeof(clientaddr));

    sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd == -1){
        INFO("socket is failed!");
        exit(-1);
    }

    serveraddr.sin_family= AF_INET;
    serveraddr.sin_addr.s_addr=inet_addr(argv[1]);
    serveraddr.sin_port=htons(atoi(argv[2]));

    if(bind(sockfd,(struct sockaddr*)&serveraddr,len)==-1){
        INFO("bind is failed!");
        exit(-1);
    }

    if(listen(sockfd,5)==-1){
        INFO("listen is failed!");
        exit(-1);
    }

    char buf[128]={0};
    struct pollfd fd[2];
    
    fd[0].fd = 0;
    fd[0].events = POLLIN;

    fd[1].fd = sockfd;
    fd[1].events = POLLIN;

    nfds_t nfds = 2;

    while(1){
        if(poll(fd,nfds,-1)==-1){
            INFO("poll is failed!");
            exit(-1);
        }

        if(fd[0].revents & POLLIN){
            fgets(buf,sizeof(buf),stdin);
            buf[strlen(buf)-1]='\0';
            INFO("buf=%s\n",buf);
        }

        if(fd[1].revents & POLLIN){
            acceptfd=accept(sockfd,(struct sockaddr*)&clientaddr,&len);
            if(acceptfd == -1){
                INFO("accept is failed");
                exit(-1);
            }
            printf("Client:[%s,%d]Linked\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));
        }
    }

    return 0;
}